﻿using LearnMAUI2.Models;
using System.Globalization;
using System.Text.Json;

namespace LearnMAUI2.Services;

public class BingImageService : ITodayImageService
{
    private readonly ITodayImageStorage _todayImageStorage;
    private readonly IAlertService _alertService;

    public BingImageService(ITodayImageStorage todayImageStorage, IAlertService alertService)
    {
        _todayImageStorage = todayImageStorage;
        _alertService = alertService;
    }
    //检查更新
    public async Task<TodayImageServiceCheckupdateResult> CheckUpdateAsync()
    {
        //从数据库中找到现有的记录，判断是否过期
        var todayImage = await _todayImageStorage.GetTodayImageAsync(false);
        if (todayImage.ExpiresAt > DateTime.Now) 
            return new TodayImageServiceCheckupdateResult { HasUpdate = true };

        //如果过期
        using var httpClient = new HttpClient();
        HttpResponseMessage response;
        try
        {
            response = await httpClient.GetAsync(
                "https://www.bing.com/HPImageArchive.aspx?format=js&idx=0&n=1&mkt=zh-CN");
            response.EnsureSuccessStatusCode();
        }
        catch (Exception e)
        {
            _alertService.Alert("Error",
                e.Message,
                "Ok");
            return new TodayImageServiceCheckupdateResult { HasUpdate = false };
        }

        var json=await response.Content.ReadAsStringAsync();
        string bingImageUrl;
        try
        {
            var bingImage = JsonSerializer.Deserialize<BingImageOfTheDay>(json, new JsonSerializerOptions { PropertyNameCaseInsensitive = true })
                ?.Images?.FirstOrDefault() ?? throw new JsonException();

            var bingImageFullStartDate = DateTime.ParseExact(
    bingImage.FullStartDate ?? throw new JsonException(),
    "yyyyMMddHHmm", CultureInfo.InvariantCulture);
            var todayImageFullStartDate = DateTime.ParseExact(
                todayImage.FullStartDate, "yyyyMMddHHmm",
                CultureInfo.InvariantCulture);

            if (bingImageFullStartDate <= todayImageFullStartDate)
            {
                todayImage.ExpiresAt = DateTime.Now.AddHours(2);
                await _todayImageStorage.SaveTodayImageAsync(todayImage, true);
                return new TodayImageServiceCheckupdateResult
                {
                    HasUpdate = false
                };
            }
            todayImage = new TodayImage
            {
                FullStartDate = bingImage.FullStartDate,
                ExpiresAt = bingImageFullStartDate.AddDays(1),
                Copyright = bingImage.Copyright ?? throw new JsonException(),
                CopyrightLink = bingImage.CopyrightLink ??
                        throw new JsonException()
            };

            bingImageUrl = bingImage.Url ?? throw new JsonException();
        }
        catch(Exception ex)
        {
            _alertService.Alert("Error", ex.Message, "Ok");
            return new TodayImageServiceCheckupdateResult { HasUpdate = false };
        }

        try
        {
            response = await httpClient.GetAsync("https://www.bing.com" + bingImageUrl);
            response.EnsureSuccessStatusCode();
        }
        catch(Exception ex)
        {
            _alertService.Alert("Error", ex.Message, "Ok");
            return new TodayImageServiceCheckupdateResult() { HasUpdate = false };
        }
        todayImage.ImageBytes=await response.Content.ReadAsByteArrayAsync();
        await _todayImageStorage.SaveTodayImageAsync(todayImage, false);
        return new TodayImageServiceCheckupdateResult
        {
            HasUpdate = true,
            TodayImage = todayImage
        };

    }

    public async Task<TodayImage> GetTodayImageAsync()
    {
        return await _todayImageStorage.GetTodayImageAsync(true);
    }
}

public class BingImageOfTheDay
{
    public List<BingImageOfTheDayImage>? Images { get; set; }
}

public class BingImageOfTheDayImage
{
    public string? StartDate { get; set; }

    public string? FullStartDate { get; set; }

    public string? EndDate { get; set; }

    public string? Url { get; set; }

    public string? Copyright { get; set; }

    public string? CopyrightLink { get; set; }
}
